package com.jic.interaction.weChatCardAndOffers.service.impl;

import com.alibaba.fastjson.JSON;
import com.jic.common.redis.RedisClientTemplate;
import com.jic.interaction.weChatCardAndOffers.common.utils.RestResult;
import com.jic.interaction.weChatCardAndOffers.common.utils.WeChatCardAndOffersHttpUtil;
import com.jic.interaction.weChatCardAndOffers.common.utils.WeChatRedisService;
import com.jic.interaction.weChatCardAndOffers.model.vo.request.WxCardRequest;
import com.jic.interaction.weChatCardAndOffers.service.WeChatCardAndOffersService;
import com.jic.market.api.manage.CouponManangeApi;
import com.jic.market.request.CouponDetailRequest;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.TreeMap;

/**
 * @Auther YGH
 * @DATE 2020/11/11/13:44
 */

@Service
@Slf4j
public class WeChatCardAndOffersServiceImpl implements WeChatCardAndOffersService {

    @Resource
    private CouponManangeApi couponManangeApi;

    @Autowired
    private WeChatRedisService weChatRedisService;

    @Value("${wz.appid}")
    private String appid;

    @Value("${wz.secret}")
    private String secret;

    @Value("${wz.url}")
    private String url;

    @Value("${wz.imagesUrl}")
    private String imagesUrl;

    @Value("${wz.imagesUrl}")
    private String addCardUrl;

    @Override
    public RestResult<T> queryCard() {
        CouponDetailRequest CouponDetailRequest = new CouponDetailRequest();
        couponManangeApi.queryCouponDetail(CouponDetailRequest);
        return null;
    }

    /**
     * @Auther: YGH
     * @DATE: 2020/11/12
     * @Param: 上传卡券的logo
     */
    @Override
    public String upLoadLogo(String filePath) {
        log.info("上传的文件路径{}", filePath);
        try {
            // String accessToken =  getWeiXinApiToken();
            // 上传文件请求路径
            String action = imagesUrl + getWeiXinApiToken() + "&type=image";
            URL url = new URL(action);
            String result = null;
            File file = new File(filePath);
            if (!file.exists() || !file.isFile()) {
                throw new IOException("上传的文件不存在");
            }
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false); // post方式不能使用缓存
            // 设置请求头信息
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");
            // 设置边界
            String BOUNDARY = "----------" + System.currentTimeMillis();
            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            // 请求正文信息
            // 第一部分：
            StringBuilder sb = new StringBuilder();
            sb.append("--"); // 必须多两道线
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"file\";filename=\""
                    + file.getName() + "\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            // 获得输出流
            OutputStream out = new DataOutputStream(con.getOutputStream());
            // 输出表头
            out.write(head);
            // 文件正文部分
            // 把文件已流文件的方式 推入到url中
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            // 结尾部分
            byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
            out.write(foot);
            out.flush();
            out.close();
            StringBuffer buffer = new StringBuffer();
            BufferedReader reader = null;
            try {
                // 定义BufferedReader输入流来读取URL的响应
                reader = new BufferedReader(new InputStreamReader(con
                        .getInputStream()));
                String line = null;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
                if (result == null) {
                    result = buffer.toString();
                }
            } catch (IOException e) {
                System.out.println("发送POST请求出现异常！" + e);
                e.printStackTrace();
                throw new IOException("数据读取异常");
            } finally {
                if (reader != null) {
                    reader.close();
                }
            }
            log.info("返回的图片路径{}", result);
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Auther: YGH
     * @DATE: 2020/11/12
     * @Return: boolean
     * @Param: WxCardRequest
     * 新增卡券
     */
    @Override
    public boolean addCard(WxCardRequest wxCardRequest) {
        String line = "";
        String message = "";
        String returnData = "";
        boolean postState = false;
        BufferedReader bufferedReader = null;
        try {
            URL urlObject = new URL(addCardUrl);
            HttpURLConnection urlConn = (HttpURLConnection) urlObject.openConnection();
            urlConn.setDoOutput(true);
            /*设定禁用缓存*/
            urlConn.setRequestProperty("Cache-Control", "no-cache");
            /*维持长连接*/
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            /*设置字符集*/
            urlConn.setRequestProperty("Charset", "UTF-8");
            /*设定输出格式为json*/
            urlConn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            /*设置使用POST的方式发送*/
            urlConn.setRequestMethod("POST");
            /*设置不使用缓存*/
            urlConn.setUseCaches(false);
            /*设置容许输出*/
            urlConn.setDoOutput(true);
            /*设置容许输入*/
            urlConn.setDoInput(true);
            urlConn.connect();
            OutputStreamWriter outStreamWriter = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
            JSONObject jsonObject = JSONObject.fromObject(wxCardRequest);
            outStreamWriter.write(jsonObject.toString());
            outStreamWriter.flush();
            outStreamWriter.close();

            /*若post失败*/
            if ((urlConn.getResponseCode() != 200)) {
                returnData = "{\"jsonStrStatus\":0,\"processResults\":[]}";
                message = "发送POST失败！" + "code=" + urlConn.getResponseCode() + "," + "失败消息：" + urlConn.getResponseMessage();
                // 定义BufferedReader输入流来读取URL的响应
                InputStream errorStream = urlConn.getErrorStream();
                if (errorStream != null) {
                    InputStreamReader inputStreamReader = new InputStreamReader(errorStream, "utf-8");
                    bufferedReader = new BufferedReader(inputStreamReader);
                    while ((line = bufferedReader.readLine()) != null) {
                        message += line;
                    }
                    inputStreamReader.close();
                }
                errorStream.close();
                System.out.println("发送失败！错误信息为：" + message);
            } else {
                /*发送成功返回发送成功状态*/
                postState = true;

                // 定义BufferedReader输入流来读取URL的响应
                InputStream inputStream = urlConn.getInputStream();

                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
                bufferedReader = new BufferedReader(inputStreamReader);

                while ((line = bufferedReader.readLine()) != null) {
                    message += line;
                }
                returnData = message;
                inputStream.close();
                inputStreamReader.close();

                System.out.println("发送POST成功！返回内容为：" + returnData);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            return postState;
        }
    }

    //获取微信access_token
    @Override
    public String getWeiXinApiToken() {
        String access_token = null;
        access_token = weChatRedisService.getValue("WeChatAccessToken");
        if("".equals(access_token)){ log.info("数据库中存在access_token=======================================");
        log.info("获取access_token url 地址为:{}", url);
        url = url + "token?";
        Map<String, String> map = new TreeMap<>();
        map.put("grant_type", "client_credential");
        map.put("appid", appid);
        map.put("secret", secret);
        String result = WeChatCardAndOffersHttpUtil.sendGet(url, map);
        Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
        log.info("-----------------------getWeiXinApiToken的日志" + resultMap);
        if (resultMap.get("success").toString().equals("false")) {
            log.error("获取token失败，错误码为{},错误信息为{} ", resultMap.get("resultCode"), resultMap.get("resultMessage"));
            return "获取token失败，错误码为{},错误信息为"+ resultMap.get("resultMessage");
        }
        access_token = (String) resultMap.get("access_token");
        Long expires_in = (Long) resultMap.get("expires_in");
            weChatRedisService.setValue("WeChatAccessToken",access_token,expires_in);
        }
        log.info("数据库中存在access_token=======================================");
        return access_token;
    }

    /*
    //获取 weixinapitoken
    public String getWeiXinApiToken() throws Exception {

        String access_token = null;
        access_token = redisService.get(redisServiceEx.getWeiXinApiTokenKey());

        if (null == access_token) {
            String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret);
            OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
            mBuilder.sslSocketFactory(createSSLSocketFactory());
            mBuilder.hostnameVerifier(new WeChatCardAndOffersServiceImpl.TrustAllHostnameVerifier());
            OkHttpClient client = mBuilder.build();

            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();
            Response response = client.newCall(request).execute();
            String result = response.body().string();
            Map<String, Object> map = objectMapper.readValue(result, Map.class);
            log.info("-----------------------getWeiXinApiToken的日志" + map);
            access_token = (String) map.get("access_token");
            Integer expires_in = (Integer) map.get("expires_in");
            redisService.setex(redisServiceEx.getWeiXinApiTokenKey(), new Integer(expires_in - 200), access_token);
        }
        return access_token;
    }
    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
    private static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;

        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new WeChatCardAndOffersServiceImpl.TrustAllCerts()}, new SecureRandom());

            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }

        return ssfFactory;
    }
    private static class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }*/

}
